home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Extra 1996 #3
/
AmigaPlus_CD-ROM-EXTRA_Nr.3.bin
/
aminet-spiele
/
zwei spieler
/
lordofhosts
/
lohsrc.lzh
/
moves.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-05-10
|
11KB
|
316 lines
/* LORD OF HOSTS - moves.c --- Verarbeitung der Spielzüge */
#include "Lord.h"
extern UBYTE whatsonboard[8][8];
extern UBYTE fval[16][8][8];
extern UBYTE kval[16][8][8];
extern struct Piece ThePieces[16];
extern int status;
struct Move Moves[MAXUNDO];
int undopos,redotop,undobot,last_error;
int NumPieces[2]= { 8,8 };
int check_move(UBYTE board[][8], struct Piece *Pieces, int Num,
UBYTE tox, UBYTE toy)
{
int i,result=0, value = Pieces[Num].Value;
UBYTE fromx = Pieces[Num].x ,fromy = Pieces[Num].y,
base= (Num<8 ? 0 : 8);
/* Stimmt die Entfernung ? */
if (ABS(fromx-tox) + ABS(fromy-toy) < value) result = MUST_MOVE_FARTHER;
if (ABS(fromx-tox) + ABS(fromy-toy) > value) result = DIST_EXCEEDED;
/* Sitzt am Ende ein eigener Spielstein ? */
if (whatsonboard[tox][toy] >= base && whatsonboard[tox][toy] <= base+7)
result |= CANT_BEAT_BUDDY;
/* Ist der Weg frei ? */
result |= how_to_move(board,fromx,fromy,tox,toy);
/* Gerät durch diesen Zug der eigene King in Gefahr ? */
if (result == MOVE_X_FIRST || result == MOVE_Y_FIRST)
result |= check_check(board,Pieces,Num,tox,toy);
return result;
}
int how_to_move(UBYTE board[][8],
UBYTE fromx, UBYTE fromy, UBYTE tox, UBYTE toy)
{
int xdist = tox-fromx, ydist = toy-fromy,
xstep = 0, ystep = 0, i;
BOOL freexfirst = TRUE, freeyfirst = TRUE;
if (xdist) xstep = xdist / ABS(xdist);
if (ydist) ystep = ydist / ABS(ydist);
/* Ohne Abbiegen ? */
if (!ydist)
{
for (i=fromx+xstep; i!=tox; i+=xstep)
if (board[i][fromy] != NOT_OCCUPIED) freexfirst = FALSE;
if (freexfirst) return MOVE_X_FIRST; else return WAY_BLOCKED;
}
if (!xdist)
{
for (i=fromy+ystep; i!=toy; i+=ystep)
if (board[fromx][i] != NOT_OCCUPIED) freeyfirst = FALSE;
if (freeyfirst) return MOVE_Y_FIRST; else return WAY_BLOCKED;
}
/* Mit Abbiegen */
/* Geht's, wenn wir zuerst in x-Richtung laufen ? */
for (i=fromx+xstep; i!=tox+xstep; i+=xstep)
if (board[i][fromy] != NOT_OCCUPIED) freexfirst = FALSE;
if (freexfirst)
for (i=fromy+ystep; i!=toy; i+=ystep)
if (board[tox][i] != NOT_OCCUPIED) freexfirst = FALSE;
if (!freexfirst) /* Wenn nicht, geht's dann mit y zuerst ? */
{
for (i=fromy+ystep; i!=toy+ystep; i+=ystep)
if (board[fromx][i] != NOT_OCCUPIED) freeyfirst = FALSE;
if (freeyfirst)
for (i=fromx+xstep; i!=tox; i+=xstep)
if (board[i][toy] != NOT_OCCUPIED) freeyfirst = FALSE;
}
if (freexfirst) return MOVE_X_FIRST;
if (freeyfirst) return MOVE_Y_FIRST;
return WAY_BLOCKED;
}
int check_check(UBYTE board[][8], struct Piece *Pieces, int Num,
UBYTE tox, UBYTE toy)
{
UBYTE checkboard[8][8], checkx, checky, fromx, fromy;
int i,j,result,base = (Num<8 ? 0 : 8), value;
for (i=0; i<=7; ++i)
for (j=0; j<=7; ++j)
checkboard[i][j] = board[i][j];
checkboard[tox][toy] = Num;
checkboard[Pieces[Num].x][Pieces[Num].y] = NOT_OCCUPIED;
if (Num != base)
{
checkx = Pieces[base].x;
checky = Pieces[base].y;
}
else
{
checkx = tox;
checky = toy;
}
j = 8 - base;
for (i=j; i<=j+7; ++i)
{
fromx = Pieces[i].x;
fromy = Pieces[i].y;
value = Pieces[i].Value;
if (Pieces[i].StillAlive == TRUE)
if (!(fromx == tox && fromy == toy))
{
if (ABS(fromx-checkx) + ABS(fromy-checky) == value)
{
result = how_to_move(checkboard,fromx,fromy,checkx,checky);
if (result == MOVE_X_FIRST || result == MOVE_Y_FIRST)
return KING_IN_DANGER;
}
}
}
return 0;
}
int do_move(UBYTE board[][8], struct Piece *Pieces, int Num,
UBYTE tox, UBYTE toy, BOOL x_first)
{
UBYTE fromx = Pieces[Num].x, fromy = Pieces[Num].y,checkvalue;
int result=0,color,base,p,i,j,r2,beaten;
SetPiece(Pieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
if (x_first)
{
MovePiece(fromx,fromy,tox-fromx,0,TRUE);
if (toy != fromy) MovePiece(tox,fromy,0,toy-fromy,FALSE);
}
else
{
MovePiece(fromx,fromy,0,toy-fromy,TRUE);
if (tox != fromx) MovePiece(fromx,toy,tox-fromx,0,FALSE);
}
board[fromx][fromy] = NOT_OCCUPIED;
beaten = NOBODY;
if (board[tox][toy] != NOT_OCCUPIED)
{
beaten = board[tox][toy];
result |= ENEMY_KNIGHT_BEATEN;
Pieces[board[tox][toy]].StillAlive = FALSE;
color = (Num < 8 ? 1 : 0); /* color = Farbe des Gegners */
--NumPieces[color];
if (NumPieces[color] < 3)
result |= ENEMY_OUT_OF_KNIGHTS; /* Spiel gewonnen */
}
board[tox][toy] = Num;
Pieces[Num].x = tox;
Pieces[Num].y = toy;
Pieces[Num].Value = fval[Num][tox][toy];
SetPiece(Pieces[Num], TRUE, FALSE); /* einblenden, keine Ausblendfarbe */
/* Moves[] für Undo/Redo setzen */
Moves[undopos].fromx = fromx;
Moves[undopos].fromy = fromy;
Moves[undopos].tox = tox;
Moves[undopos].toy = toy;
Moves[undopos].Beaten= beaten;
Moves[undopos].x_first = x_first;
Moves[undopos].status = status | WAITING_FOR_PICK;
Moves[undopos].status &= (~(WAITING_FOR_DEST|WAITING_FOR_CONF));
/* undopos : Position im Undo/Redo-Puffer
* redotop : wenn undopos == redotop, dann ist kein Redo möglich
* undobot : wenn undopos == undobot, dann ist kein Undo möglich */
undopos = (undopos+1) % MAXUNDO;
if (undopos == undobot) undobot = (undobot+1) % MAXUNDO;
redotop = undopos;
/* Check, ob Check */
base = (Num < 8 ? 0 : 8);
tox = Pieces[8-base].x;
toy = Pieces[8-base].y;
for (i=base; i<=base+7; ++i)
{
fromx=Pieces[i].x;
fromy=Pieces[i].y;
if (Pieces[i].StillAlive == TRUE)
{
checkvalue = Pieces[i].Value;
if (checkvalue == 0) checkvalue =kval[i][Pieces[i].x][Pieces[i].y];
if (ABS(fromx-tox) + ABS(fromy-toy) == checkvalue)
{ /* Pieces[i].Value geht nicht, da er mit
kval[i][x][y] ausgetauscht sein könnte ! */
r2 = how_to_move(board,fromx,fromy,tox,toy);
if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
result |= ENEMY_KING_BEATABLE;
}
}
}
/* Check, ob Matt */
if (result & ENEMY_KING_BEATABLE)
{
r2=1;
for (p = 8-base; p<=15-base && r2 > 0; ++p) /* gegnerische Spielsteine */
{
if (Pieces[p].StillAlive)
{
for (i=-Pieces[p].Value; i<=Pieces[p].Value && r2 > 0; ++i)
{
j=Pieces[p].Value-ABS(i); /* ABS(i)+ABS(j) = Value */
if (Pieces[p].x+i >=0 && Pieces[p].x+i <=7
&& Pieces[p].y+j >=0 && Pieces[p].y+j <=7)
{
r2 = check_move(board,Pieces,p,Pieces[p].x+i,Pieces[p].y+j);
if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
r2=-1;
}
if (r2 > 0)
{
j=-Pieces[p].Value+ABS(i); /* ABS(i)+ABS(j) = Value */
if (Pieces[p].x+i >=0 && Pieces[p].x+i <=7
&& Pieces[p].y+j >=0 && Pieces[p].y+j <=7)
{
r2 = check_move(board,Pieces,p,Pieces[p].x+i,Pieces[p].y+j);
if (r2 == MOVE_X_FIRST || r2 == MOVE_Y_FIRST)
r2=-1;
}
}
}
}
}
if (r2 != -1)
result |= ENEMY_MATED;
}
if (result & ENEMY_OUT_OF_KNIGHTS || result & ENEMY_MATED)
Moves[undopos].GameOver = TRUE;
else
Moves[undopos].GameOver = FALSE;
return result;
}
BOOL undo(void)
{
int Num;
UBYTE fromx,fromy,tox,toy;
if (undobot == undopos) return FALSE; /* konnte Undo nicht durchführen */
--undopos;
if (undopos < 0) undopos += MAXUNDO; /* wraparound buffer */
fromx = Moves[undopos].tox; /* Undo vertauscht hin und zurück */
fromy = Moves[undopos].toy;
tox = Moves[undopos].fromx;
toy = Moves[undopos].fromy;
Num = whatsonboard[fromx][fromy];
SetPiece(ThePieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
if (!Moves[undopos].x_first)
{
if (tox != fromx)
{
MovePiece(fromx,fromy,tox-fromx,0,TRUE);
MovePiece(tox,fromy,0,toy-fromy,FALSE);
}
else
MovePiece(fromx,fromy,0,toy-fromy,TRUE);
}
else /* x_first == TRUE */
{
if (toy != fromy)
{
MovePiece(fromx,fromy,0,toy-fromy,TRUE);
MovePiece(fromx,toy,tox-fromx,0,FALSE);
}
else
MovePiece(fromx,fromy,tox-fromx,0,TRUE);
}
ThePieces[Num].x = tox;
ThePieces[Num].y = toy;
ThePieces[Num].Value = fval[Num][tox][toy];
whatsonboard[tox][toy] = Num;
whatsonboard[fromx][fromy] = NOT_OCCUPIED;
SetPiece(ThePieces[Num], TRUE, FALSE); /* einblenden, keine Ausblendfarbe */
if (Moves[undopos].Beaten != NOBODY)
{
ThePieces[Moves[undopos].Beaten].StillAlive = TRUE; /* Revival */
SetPiece(ThePieces[Moves[undopos].Beaten], TRUE, FALSE);
whatsonboard[fromx][fromy] = Moves[undopos].Beaten;
NumPieces[(Moves[undopos].Beaten > 7)]++;
}
return TRUE;
}
BOOL redo(void)
{
int Num;
UBYTE fromx,fromy,tox,toy;
if (redotop == undopos) return FALSE; /* konnte Redo nicht durchführen */
fromx = Moves[undopos].fromx;
fromy = Moves[undopos].fromy;
tox = Moves[undopos].tox;
toy = Moves[undopos].toy;
Num = whatsonboard[fromx][fromy];
SetPiece(ThePieces[Num], FALSE, TRUE);/* nicht einblenden, Ausblendfarbe an */
if (Moves[undopos].x_first)
{
MovePiece(fromx,fromy,tox-fromx,0,TRUE);
if (toy != fromy) MovePiece(tox,fromy,0,toy-fromy,FALSE);
}
else
{
MovePiece(fromx,fromy,0,toy-fromy,TRUE);
if (tox != fromx) MovePiece(fromx,toy,tox-fromx,0,FALSE);
}
ThePieces[Num].x = tox;
ThePieces[Num].y = toy;
ThePieces[Num].Value = fval[Num][tox][toy];
whatsonboard[tox][toy] = Num;
whatsonboard[fromx][fromy] = NOT_OCCUPIED;
SetPiece(ThePieces[Num], TRUE, FALSE); /* einblenden, keine Ausblendfarbe */
if (Moves[undopos].Beaten != NOBODY)
{
ThePieces[Moves[undopos].Beaten].StillAlive = FALSE; /* Wieder tot */
NumPieces[(Moves[undopos].Beaten>7)]--;
}
undopos = (undopos+1) % MAXUNDO; /* wraparound buffer */
return TRUE;
}